package com.datapermission.aspect;

import com.datapermission.annotation.Permission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayDeque;
import java.util.Deque;

public class PermissionContext {

    /**
     * 让子线程可以继承主线程的信息
     */
    private static final InheritableThreadLocal<Deque<Permission>> CONTEXT_HOLDER =
            new InheritableThreadLocal<Deque<Permission>>() {
                @Override
                protected Deque<Permission> initialValue() {
                    return new ArrayDeque<>();
                }

                @Override
                protected Deque<Permission> childValue(Deque<Permission> parentValue) {
                    // 返回父线程的副本，以确保子线程继承相同的数据
                    return new ArrayDeque<>(parentValue);
                }
            };
    private static final Logger log = LoggerFactory.getLogger(PermissionContext.class);

    public static void set(Permission deptPermission) {
        CONTEXT_HOLDER.get().push(deptPermission);
    }

    public static Permission get() {
        Deque<Permission> stack = CONTEXT_HOLDER.get();
        return stack.isEmpty() ? null : stack.peek();
    }

    public static void clear() {
        Deque<Permission> stack = CONTEXT_HOLDER.get();
        if (!stack.isEmpty()) {
            stack.pop();
        }
        if (stack.isEmpty()) {
            log.info("成功清理threadLocal");
            CONTEXT_HOLDER.remove();
        }
    }

    /**
     * 提供手动清理的方法,给调用子线程结束后手动清理自己的threadLocal
     */
    public static void manualClear() {
        CONTEXT_HOLDER.remove();
    }
}
